/*
命令模式是一种行为型设计模式，它将请求封装为一个对象，从而使你可以将不同的请求参数化，并且能够在不同的时间点执行或者排队请求。

在命令模式中，有四个主要的角色：

命令（Command）：定义了执行操作的接口，并包含了执行操作的方法。
具体命令（ConcreteCommand）：实现了命令接口，并且包含了具体的操作逻辑。

接收者（Receiver）：执行具体操作的对象。
调用者（Invoker）：接收命令并执行命令的对象。
以下是一个简单的命令模式的实现示例： 

*/ 

//定义命令接口
var Command={
	execute:function(){}
}

//定义具体命令
function ConcreteCommand(receiver){
	this.receiver=receiver;
	this.execute=function(){ 
		 this.receiver.action();
	}
}


//定义接收者
function Receiver(){
	this.action=function(){
		console.log("receiver:执行操作");
	}
}


//定义调用者
function Invoker(command){
	this.command=command;
	this.executeCommand=function(){
		this.command.execute();
	}
}

//使用命令模式
var receiver=new Receiver();
// console.log(receiver);              
var command=new ConcreteCommand(receiver);              
// console.log(command); 
var invoker=new Invoker(command); 
// console.log(invoker);

invoker.executeCommand();//// 输出：Receiver: 执行操作


/*
在上述案例中，我们定义了一个命令接口 Command，它包含了一个 execute 方法。
然后，我们创建了一个具体命令类 ConcreteCommand,它实现了命令接口，并在 execute 方法中调用了接收者对象的操作方法。 
接收者对象 Receiver 定义了具体的操作逻辑，即 action 方法。 
调用者对象 Invoker 接收一个命令对象，并通过调用 executeCommand 方法来执行该命令。 
通过使用命令模式，我们可以将请求封装为一个对象，并且能够在不同的时间点执行或者排队请求。
这样，我们可以更灵活地处理请求，而无需直接与接收者对象进行交互。  
*/

//应用案例1

//Receiver角色
class Player{
	play(){
		console.log("开始播放");
	}
	speed(){
		console.log("拖动进度条");
	}
	stop(){
		console.log("停止播放");
	}
	pause(){
		console.log("暂停播放");
	}
}

//定义具体命令角色
 class StopAction{ 
 	constructor(player){
 		this.player=player;
 	}
 	execute(){
 		this.player.stop();
 	}
 }
 
 class PauseAction{
 	constructor(player){
 		this.player=player;
 	}
 	execute(){
 		this.player.pause();
 	}
 }
 class PlayAction{
 	constructor(player){
 		this.player=player;
 	} 
 	execute(){ 
 		this.player.play();
 	}
 }

 class SpeedAction{
 	constructor(player){
 		this.player=player;
 	}
 	execute(){
 		this.player.speed();
 	}
 }

//Invoker角色
class Controller{
	actionList=[];
	//添加命令
	addAction(args){
		this.actionList.push(args);
	}
	//执行
	execute(action){
		action.execute();
	}
	//
	executes(){
		this.actionList.forEach(item=>{
			item.execute();
		}) 
	} 
}

 

let player=new Player(); 
let control=new Controller();   
control.execute(new PlayAction(player));  //执行一条命令

//执行N条命令
control.addAction(new PlayAction(player));
control.addAction(new StopAction(player));
control.addAction(new SpeedAction(player));
control.addAction(new PauseAction(player));

control.executes();



